package com.jrx.anytxn.transaction.timer.job.allocation.config;

import com.jrx.anytxn.ribbon.config.GrayVersionConfig;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.TlPaymentLog;
import com.jrx.anytxn.transaction.handler.IPaymentHandler;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlPaymentLogMapper;
import com.jrx.anytxn.transaction.timer.config.AnytxnBatchProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 还款任务
 *
 * @author jing.xy
 */
@Configuration
@EnableConfigurationProperties(AnytxnBatchProperties.class)
public class AllocationConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(AllocationConfiguration.class);

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    public IPaymentHandler paymentHandler;

    @Autowired
    public GrayVersionConfig grayVersionConfig;


    @Resource
    private ExtTlPaymentLogMapper extTlPaymentLogMapper;

    @Autowired
    AnytxnBatchProperties anytxnBatchProperties;


    @Bean
    public Job allocationJob() {
        return jobBuilderFactory.get("allocationJob")
                .start(allocationStep())
                .build();
    }

    @Bean
    public Step allocationStep() {
        return stepBuilderFactory.get("allocationStep")
                .tasklet(allocationTasklet())
                .build();
    }

    @Bean
    @StepScope
    public Tasklet allocationTasklet() {
        logger.info("还款分配开始");
        return (stepContribution, chunkContext) -> {
            List<TlPaymentLog> logList = extTlPaymentLogMapper.selectBySumStatusForAllocation(TransBizConstant.PAYMENT_LOG_SUM_STATUS_T, grayVersionConfig.getCurrentVersion());
            ExecutorService service = Executors.newFixedThreadPool(anytxnBatchProperties.getAllocationConfig().getThrottleLimit());
            List<CompletableFuture<Void>> list = logList.stream().map(log ->
                    CompletableFuture.runAsync(() ->
                            {
                                try {
                                    paymentHandler.paymentAllocation(log);
                                } catch (Exception e) {
                                    logger.error("差错异常：",e);
                                }
                            }
                    , service)
            ).collect(Collectors.toList());
            long count = list.stream().map(CompletableFuture::join).count();
            logger.info("最终结果数{}",count);
            service.shutdown();
            return RepeatStatus.FINISHED;
        };
    }
}
